<template>

  <div class="app-container">
    <el-form ref="generateForm" :model="form" label-width="120px">
      <el-row>
        <el-col :span="24">
          <el-form-item label="账号ID：">
            <el-select class="form-control" v-model="form.accountId" placeholder="请选择账号ID" filterable   @change="onAccontChange">
                <el-option
                  v-for="(accountId, idx) in accountIds"
                  :key="idx"
                  :label="accountId"
                  :value="accountId"
                />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-row>
        <el-col :span="24">
          <el-form-item label="账号偏好：">
            <preference-panel v-model="preferenceForm" @archive="onPreferenceArchive"/>
          </el-form-item>
        </el-col>
      </el-row>



      <el-row>
        <el-col :span="24">
          <el-form-item label="">
            <div class="generate-bar">
              <label>生成条数：</label>
              <el-input-number :disabled="!form.accountId" class="generate-number" :min="1" v-model="form.total" />
                <el-button :disabled="!form.accountId" type="success" @click="generateScriptText">生成脚本</el-button>
                <div class="generate-stats">
                  <span class="text-error">{{ allUrlText ? allUrlText.split('\n').length :
                    0}}</span> / {{ form.total }}
                </div>
            </div>

          </el-form-item>


        </el-col>

      </el-row>

      <el-row >
        <el-col :span="12">
          <el-form-item label="跟单链接：" prop="genText">
            <el-input :disabled="!form.accountId" type="textarea" spellcheck="false" v-model="form.trackText" :rows="16" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="生成链接" prop="genText">
            <el-input :disabled="!form.accountId" type="textarea" spellcheck="false" v-model="form.genText" :rows="16" />
          </el-form-item>
        </el-col>
      </el-row>


    </el-form>


      <div class="footer">
        <el-button :disabled="!allUrlText" :id="'btn-copy-' + copyId">复制全部</el-button>
        <el-button :disabled="!allUrlText" type="primary" @click="exportTxt">
          合并导出txt
        </el-button>
      </div>

  </div>

</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import * as accountService from '@/api/service/AccountService'
import * as selectionService from '@/api/service/SelectionService'
import * as dailyService from '@/api/service/DailyService'
import PreferencePanel from '@/components/feishu/PreferencePanel.vue'
import { Operator } from '@/framework/common/constants'
import DateUtil from '@/framework/utils/date-util'
import { isEmpty, isNotEmpty } from '@/framework/common/functions'
import { SECOND_CATEGORY } from '@/api/service/CategoryService'

import { saveAs } from 'file-saver'
import ClipboardJS from 'clipboard';

const globalVal = globalThis as any;


defineOptions({ name: "ScriptIndex" });


const form: any = ref({
  accountId: null,
  genText: '', // 生成链接
  trackText: '', // 跟踪链接
  total: 20
})
const copyId = ref(new Date().getTime())
const loading = ref(false)
const accountIds = ref<string[]>([])
const selections:any[] = <any>[];
const dailySelections:any[] = <any>[];
const accounts:any[] = <any>[];
const preferenceForm = ref<any>(null)
const containTrack = ref(true) // 是否包含跟单链接



/**
 * 全部链接文本
 */
const allUrlText = computed(()=>{
  let text = '';
  if(form.value.trackText){
    text += form.value.trackText.trim();
  }
  if(form.value.genText){
    text += '\n' + form.value.genText.trim();
  }
  return text.trim()

})

/**
 * 偏好存档
 * @param e
 */
function onPreferenceArchive(e:any){
  if(!e.data){
    return
  }
  let data = e.data;
  let account = accounts.filter(item => item['账号ID'] === data['账号ID'])[0]
  if(account){
    account['偏好设置'] = data['偏好设置']
  }
  else{
    account = {
      ... data
    }
    accounts.push(account);
  }



}

/**
 * 生成脚本
 */
function generateScriptText(): void {
  if(!form.value.total){
    globalVal.error('请设置要生成的链接数');
    return ;
  }
  const trackUrls = form.value.trackText.trim().split('\n')
  const needNumber = form.value.total - trackUrls.length;

  if(needNumber < 1){
    globalVal.error('跟单链接数量已充足');
    return ;
  }


  const dateFilter = preferenceForm.value.preference.date as DateFilterCondition;
  const commissionFilter = preferenceForm.value.preference.commission as CommissionFilterCondition;
  const categoryFilter = preferenceForm.value.preference.category as CategoryFilterCondition;


  let filterSelections = selections
  let filterDailySelections = dailySelections;

  /**
   * 日期过滤
   * date: [
      { label: '最近', value: Operator.recent },
      { label: '等于', value: Operator.equals },
      { label: '早于', value: Operator.before },
      { label: '介于', value: Operator.between }
    ],
   */
  if(dateFilter.enable){
    if(dateFilter.operator === Operator.recent){
      if(!dateFilter.recent){
        globalVal.error('请设置好最近天数');
        return ;
      }
      const targetDate = DateUtil.before(dateFilter.recent);
      filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] > targetDate.getTime())
    }
    else if(dateFilter.operator === Operator.equals
    || dateFilter.operator === Operator.before
    || dateFilter.operator === Operator.after){
      const targetDate = dateFilter.values[0] as Date
      const dateBegin = DateUtil.dateBegin(targetDate);
      let dateEnd = DateUtil.dateEnd(targetDate);
      if(!targetDate){
        globalVal.error('请设置好日期');
        return ;
      }
      if(dateFilter.operator === Operator.equals){
        filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] >= dateBegin.getTime() && selection['日期'] <= dateEnd.getTime())
        filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] >= dateBegin.getTime() && selection['日期'] <= dateEnd.getTime())
      }
      else if(dateFilter.operator === Operator.before){
        filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] < dateBegin.getTime())
        filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] < dateBegin.getTime())
      }
      else if(dateFilter.operator === Operator.after){
        filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] > dateEnd.getTime())
        filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] > dateEnd.getTime())
      }
      else if(dateFilter.operator === Operator.between){
          dateEnd = DateUtil.dateEnd(dateFilter.values[1] as Date)
          filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] >= dateBegin.getTime() && selection['日期'] <= dateEnd.getTime())
          filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['日期']) && selection['日期'] >= dateBegin.getTime() && selection['日期'] <= dateEnd.getTime())
      }
    }

  }


  /**
   * 佣金
   * { label: '等于', value: Operator.equals },
    { label: '大于', value: Operator.greater },
    { label: '小于', value: Operator.less },
    { label: '大于等于', value: Operator.greaterEqual },
    { label: '小于等于', value: Operator.lessEqual },
    { label: '介于', value: Operator.between }
   */
  if(commissionFilter.enable){

    if(commissionFilter.operator === Operator.between){
      let begin = commissionFilter.values[0] as number | null;
      let end = commissionFilter.values[1] as number | null;
      if(begin === null || begin === undefined){
        globalVal.error('请设置佣金起始值');
        return ;
      }
      if(end === null || end === undefined){
        globalVal.error('请设置佣金截止数值');
        return ;
      }
      if(begin > end){
        globalVal.error('佣金截止数值不能小于起始数值');
        return ;
      }

      //百分比转小数
      begin = begin / 100;
      end = end / 100;
      filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] >= begin && selection['佣金'] <= end)
      filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] >= begin && selection['日期'] <= end)


    }
    else{
      let value = commissionFilter.values[0] as number;
      if(value === null || value === undefined){
        globalVal.error('请设置佣金数值');
        return ;
      }
      console.log(value, value/ 100)
      value = value / 100;


      switch(commissionFilter.operator){
        case Operator.equals:
          filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] === value)
          filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] === value)
          break;


        case Operator.greater:
          filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] > value)
          filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] > value)
          break;

        case Operator.less:
          filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] < value)
          filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] < value)
          break;

        case Operator.greaterEqual:
          filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] >= value)
          filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] >= value)
          break;

        case Operator.lessEqual:
          filterSelections = filterSelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] <= value)
          filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection['佣金']) && selection['佣金'] <= value)
          break;
      }

    }
  }


  /**
   * 分类
   */
  if(categoryFilter.enable){
    let items = categoryFilter.items.filter(item => isNotEmpty(item.second) && isNotEmpty(item.weight));
    if(items.length === 0){
      globalVal.error('请至少设置一个有效的分类配置');
      return ;
    }
    items.forEach(item => {
      if(isEmpty(item.second) && isNotEmpty(item.weight)){
        globalVal.error('请选择要配置的分类');
        return ;
      }
      else if(isNotEmpty(item.second) && !item.weight){
        globalVal.error('请配置好权重');
        return ;
      }

      filterSelections = filterSelections.filter(selection=> isNotEmpty(selection[SECOND_CATEGORY]) && selection[SECOND_CATEGORY] === item.second)
      filterDailySelections = filterDailySelections.filter(selection=> isNotEmpty(selection[SECOND_CATEGORY]) && selection[SECOND_CATEGORY] === item.second)
    })





    // 生成链接
    let matchUrls:string[] = []
    const urlMap = new Map<string, string[]>();
    filterDailySelections.forEach(selection => {
      const category = selection[SECOND_CATEGORY]
      const urls:string[] = urlMap.has(category) ? urlMap.get(category) as string[] : []
      const url = selection['产品链接'];
      if(url && !urls.includes(url)){
        urls.push(url)
        urlMap.set(category, urls);
      }

      if(url && !matchUrls.includes(url) && !trackUrls.includes(url)){
        matchUrls.push(url)
      }
    })

    if(containTrack.value){
      filterSelections.forEach(selection=>{
        const category = selection[SECOND_CATEGORY]
        const urls:string[] = urlMap.has(category) ? urlMap.get(category) as string[] : []
        getTrackUrls(selection).forEach(item => {
          if(!urls.includes(item)){
            urls.push(item);
          }

          if(!matchUrls.includes(item) && !trackUrls.includes(item)){
            matchUrls.push(item);
          }
        })
        urlMap.set(category, urls);
      })
    }

    if(matchUrls.length < needNumber){
      globalVal.toast(`满足条件的链接不够，只有${matchUrls.length}条`);
      form.value.genText = matchUrls.join('\n')
    }
    else{
      matchUrls = [];
      let totalWeidht = 0;
      items.forEach(item => {
        totalWeidht += item.weight || 0;
      })
      while(true){
        let rand = Math.random() * totalWeidht;
        let weight = 0;
        for(let i = 0; i < items.length; i++){
          let item = items[i];
          weight += item.weight || 0;
          if(weight > rand){
            const category = item.second as string;
            const urls:string[] = urlMap.has(category) ? urlMap.get(category) as string[] : []
            if(urls.length > 0){
              urls.sort((a, b) => {
                void a
                void b
                return Math.random() - 0.5;
              })
              const url = urls.pop();
              if(url && !matchUrls.includes(url) && !trackUrls.includes(url)){
                matchUrls.push(url)
              }
              urlMap.set(category, urls);
            }
            break;
          }
        }

        if(matchUrls.length == needNumber){
          break;
        }

        let count = 0;
        urlMap.forEach(urls=> {
          count += urls.length;
        })
        // 无数量
        if(count == 0){
          globalVal.toast(`满足条件的链接不够，只有${matchUrls.length}条`);
          break;
        }

      }

      form.value.genText = matchUrls.join('\n')
    }



  }
  else{
    let matchUrls:string[] = []
    filterDailySelections.forEach(selection => {
      const url = selection['产品链接'];
      if(url && !matchUrls.includes(url) && !trackUrls.includes(url)){
        matchUrls.push(url)
      }
    })

    if(containTrack.value){
      filterSelections.forEach(selection=>{
        let urls = getTrackUrls(selection);
        urls.forEach(item => {
          if(!matchUrls.includes(item) && !trackUrls.includes(item)){
            matchUrls.push(item);
          }
        })
      })
    }

    if(matchUrls.length < needNumber){
      globalVal.toast(`满足条件的链接不够，只有${matchUrls.length}条`);
      form.value.genText = matchUrls.join('\n')
    }
    else{
      // 随机排序
      matchUrls.sort((a, b) => {
        void a
        void b
        return Math.random() - 0.5;
      })
      form.value.genText = matchUrls.slice(0, needNumber).join('\n')
    }




  }

}


/**
 * 加载选品列表
 */
async function loadSelections(): Promise<any>{
  for await (const page of await selectionService.findList()){
    page.items.forEach(item => {
      const result = globalVal.parseFeishuRecord(item);
      const accountId = result['账号ID'];
      if( !accountIds.value.includes(accountId)){
        accountIds.value.push(accountId)
      }

      selections.push(result)
    })

  }
}

/**
 * 加载账号偏好表
 */
async function loadAccounts(): Promise<any>{
  for await (const page of await accountService.findList()){
    page.items.forEach(item => {
      accounts.push(globalVal.parseFeishuRecord(item))
    })

  }
}

/**
 * 加载日常选品公用数据
 */
async function loadDailySelections(): Promise<any>{
  for await (const page of await dailyService.findList()){
    page.items.forEach(item => {
      const result = globalVal.parseFeishuRecord(item);
      dailySelections.push(result)
    })

  }

}

/**
 * 加载页面数据
 */
function loadData(){
  loading.value = true;
  Promise.all([loadSelections(),loadAccounts(),loadDailySelections()]).finally(()=>{
    loading.value = false;
  })

}

/**
 * 获取跟踪单链接
 * @param record
 */
function getTrackUrls(record: any): string[] {
  const urls: string[] = []
  for (const key in record) {
    if (key.match('^跟单链接\\d+$')) {
      let url = record[key] as string;
      if(url){
        url = url.trim().split(' ')[0];
      }
      if(url){
        urls.push(url)
      }
    }
  }
  return urls
}

/**
 * 账号切换时
 */
function onAccontChange(): void {
  const account = accounts.filter(item => item['账号ID'] === form.value.accountId) [0]
  let preferenceJson = null;
  let recordId = null;
  if(account && account['偏好设置']){
    preferenceJson = JSON.parse(account['偏好设置'])
    recordId = account.recordId;
  }
  preferenceForm.value = {
    accountId:form.value.accountId,
    preference: preferenceJson,
    recordId: recordId
  }

  const trackUrls:string[] = []
  selections.filter(item => item['账号ID'] === form.value.accountId).forEach(item=>{
    const urls = getTrackUrls(item);

    urls.forEach(url => {
      if (!trackUrls.includes(url) && !trackUrls.includes(url)) {
        trackUrls.push(url);
      }
    })
  })
  form.value.trackText = trackUrls.join('\n')
  //selections.filter()
}



/**
 * 导出文本
 */
function exportTxt(): void {
  const blob = new Blob([form.value.genText], { type: "text/plain;charset=utf-8" });
  saveAs(blob, '脚本文件.txt');
}





onMounted(() => {
  const copyButtonId = "#btn-copy-" + copyId.value
  const clipboard = new ClipboardJS(copyButtonId, {
    text: () => {
      const codeStr = allUrlText.value
      globalVal.success('复制成功')
      return codeStr
    }
  })
  clipboard.on('error', e => {
    console.log(e)
    globalVal.error('代码复制失败')
  })
})

loadData();

</script>
<style lang="scss" scoped>

.generate-number{
  margin-right: 20px;
}
.generate-bar{
  display: flex;
  justify-content: flex-end;
  width: 100%;

}
.generate-stats{
  text-align: right;

  margin-left: 20px;
}
.footer{
  display: flex;
  justify-content: flex-end;
}
.app-container{
  :deep(.el-textarea__inner){
    resize: none;
  }
}
</style>
